/// Rust 严格的借用检查规则虽然避免了悬垂指针，保证了内存安全，但是代码的开发体验还是差强人意的。
/// 有时候严格的借用检查规则会让代码变得非常难以理解,
/// 因此， Rust 团队在 Rust 2018 版本中引入了非词法作用域生命周期(Non-Lexical Lifetime,NLL)来进行改善。
pub fn start() {
    let mut x = vec![1];
    // 写法并不被 NLL 支持。 NLL 不仅改进了借用检查器 ，还提升了错误 提示的精准度
    // x.pop() second mutable borrow occurs here
    // x.push(x.pop().unwrap());
    println!("{:?}", x);
}

struct List<T> {
    value: T,
    next: Option<Box<List<T>>>,
}

/// 2015版 在一个 loop 循环中使用了可变借用 &mut list.value，当前的借用检查器会认为
/// 这个可变借用是多次借用，从而编译报错。
/// 在使用Rust 2018版本时，该代码能够正常编译通过。
/// 也就是说 NLL 也解决了无限循环中借用检查的问题。
fn to_refs<T>(mut list: &mut List<T>) -> Vec<&mut T> {
    let mut result = vec![];
    loop {
        result.push(&mut list.value);
        if let Some(n) = list.next.as_mut() {
            list = n;
        } else {
            return result;
        }
    }
}
